/**
 *
 */
package de.cbf.cam.dice.entities;

import java.beans.IndexedPropertyChangeEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * @author Surfer
 *
 */
public class RollDataSum extends RollDataOpen {
	private static final Log logger = LogFactory.getLog(RollDataSum.class);

	protected List<RollDataOpen> rollDataSubs = new ArrayList<RollDataOpen>();

	public RollDataSum() {
		super();
//		propertyChange.addPropertyChangeListener(new PCLResult()); 	//is never fired,
																	//because setRolls/DiceSides changed
	}

	@Override
	public String toString() {
		return name;
	}
	@Override
	public int[] getRolls() {
		int[] rolls = new int[rollDataSubs.size()];
		for (int i = 0; i < rolls.length; i++) {
			rolls[i] = rollDataSubs.get(i).getRolls()[0];
		}
		return rolls;
	}

	@Override
	public void setRolls(int[] rolls) {
		if(rolls.length == rollDataSubs.size()){
			for (int i = 0; i < rolls.length; i++) {
				int[] roll = new int[1];
				roll[0] = rolls[i];
				rollDataSubs.get(i).setRolls(roll);
			}
		}else{
			logger.error(	"Wrong ThrowDataSubNumber : "+rollDataSubs.size()+"\n" +
									"For RollsNumber: "+rolls.length);
		}
	}

	public void setRolls(int[] rolls,int rollDataSubIndex){
		if (rollDataSubIndex < rollDataSubs.size()) {
			rollDataSubs.get(rollDataSubIndex).setRolls(rolls);
		}else{
			//rollDataSub does not exist
			logger.error("Not existant ThrowDataSub: "+rollDataSubIndex);
			return;
		}
	}

	@Override
	public int[] getDiceSides() {
		int[] diceSides = new int[rollDataSubs.size()];
		for (int i = 0; i < rollDataSubs.size(); i++) {
			diceSides[i] = rollDataSubs.get(i).getDiceSides()[0];
		}
		return diceSides;
	}

	@Override
	public void setDiceSides(int[] diceSides) {
		rollDataSubs.clear();
		for (int i = 0; i < diceSides.length; i++) {
			//construct rollDataOpen
			RollDataOpen rollDataOpen = new RollDataOpen();
			int[] diceSidesRoll = new int[1];
			diceSidesRoll[0] = diceSides[i];
			rollDataOpen.setDiceSides(diceSidesRoll);
			addRollDataOpen(rollDataOpen);
		}
	}

	public void setSubName(String subName,int rollDataSubIndex){
		if (rollDataSubIndex < rollDataSubs.size()) {
			rollDataSubs.get(rollDataSubIndex).setName(subName);
		}else{
			//rollDataSub does not exist
			logger.error("Not existant ThrowDataSub: "+rollDataSubIndex);
			return;
		}
	}

	public boolean addRollDataOpen(RollDataOpen rollDataOpen){
		rollDataOpen.propertyChange.addPropertyChangeListener(new PCLSumResult());
		return rollDataSubs.add(rollDataOpen);
	}
	public int getRollDataSubCount(){
		return rollDataSubs.size();
	}
	public RollDataOpen getRollDataSub(int index){
		return rollDataSubs.get(index);
	}
	public boolean removeRollDataOpen(RollDataOpen rollDataOpen){
		return rollDataSubs.remove(rollDataOpen);
	}

	public boolean addPropertyChangeListener(PropertyChangeListener pcl, int rollDataSubIndex){
		if(rollDataSubIndex < rollDataSubs.size()){
			//rollDataSub exists
			rollDataSubs.get(rollDataSubIndex).propertyChange.addPropertyChangeListener(pcl);
			return true;
		}else{
			//rollDataSub does not exist
			logger.error("Not existant RollDataSub: "+rollDataSubIndex);
			return false;
		}
	}

	public boolean removePropertyChangeListener(PropertyChangeListener pcl, int rollDataSubIndex){
		if(rollDataSubIndex < rollDataSubs.size()){
			//rollDataSub exists
			rollDataSubs.get(rollDataSubIndex).propertyChange.removePropertyChangeListener(pcl);
			return true;
		}else{
			//rollDataSub does not exist
			logger.error("Not existant ThrowDataSub: "+rollDataSubIndex);
			return false;
		}
	}

	/**
	 * @author salter
	 * computes result by results of subRollData
	 */
	private class PCLSumResult implements PropertyChangeListener{
		@Override
		public void propertyChange(PropertyChangeEvent arg0) {
			if (arg0 instanceof IndexedPropertyChangeEvent) {
				IndexedPropertyChangeEvent indexedPCE = (IndexedPropertyChangeEvent) arg0;
				switch (indexedPCE.getIndex()) {
					case PropertyIndexResult:{ //if result of one sub part changes compute sum result again
						int result = 0;
						for (RollDataOpen rollOpen : rollDataSubs) {
							result += rollOpen.getResult();
						}
						result += getModifierValue();//if special modifiers are placed on the sum directly
						setResult(result);//on this object (SumResult)
						break;
					}
				}
			}
		}
	}



}
